/******************************************************************************
 *      Mestrado em Ciencia da Computacao - UFMS
 *		Redes de Computadores - Prof. Dr. Ronaldo Alves Ferreira
 *		Alunos: Geraldo Landre, Marcel Tolentino, Vinicius Bueno
 *****************************************************************************/
/* tcpinp.c - tcpinp */

#include "thread.h"
#include "tcpfms.h"
#include "tcb.h"
#include "defines.h"

/*------------------------------------------------------------------------
 *  tcpinp - lidar com um segmento TCP vindo do IP
 *------------------------------------------------------------------------
 */

//verificar
void tcpinp()
{
    struct  udp *pudp;
    struct  tcp	*ptcp;
    struct  tcb	*ptcb;

    while (1)
    {
        thread_wait(input_thread); // suspend/resume

        pudp = (struct udp *)thread_recvmsg(input_thread);
        if ((int)pudp == SYSERR)
            break;
        
        
        if (tcpcksum(pudp, pudp->udp_len)) {
            ++TcpInErrs;
            free(pudp);
            continue;
        }
        ptcp = (struct tcp*)(pudp->udp_data);
        
        printf("sport: %d\tdport: %d", ptcp->tcp_sport, ptcp->tcp_dport);
        //printf("alterando porta da tcb %d, de %d, para %d");

        tcpnet2h(ptcp); // convert all fields to host order
 //     ptcp->ep_order |= EPO_TCP;
        ptcb = tcpdemux(pudp);
        if (ptcb == 0)
        {
            ++TcpInErrs;
            tcpreset(pudp);
            free(pudp);
            continue;
        }
        if (!tcpok(ptcb, pudp))
            tcpackit(ptcb, pudp);
        else
        {
            tcpopts(ptcb, pudp);
            tcpswitch[ptcb->tcb_state](ptcb, pudp);
        }
        if (ptcb->tcb_state != TCPS_FREE)
            sem_post( &(ptcb->tcb_mutex) );
        free(pudp);
    }
}